<?php
/**
 * Base abstract class for a large database query
 *
 * @package Concerto
 * @subpackage Initializers
 * @author Jason Raede <jason@torchdm.com>
 */
namespace application\initializers;

abstract class ConcertoQuery {

	/**
	 * Array of query arrays, for multiple nested queries
	 *
	 * Array structure is as follows:
	 * * 'results'=>array of DBModel subclasses, depending on the query (either Content or User)
	 * * 'current'=>The pointer to the current result, used for looping
	 * * 'limit'=>Results per page
	 * * 'lastPage'=>The last page, according to the 'limit' parameter
	 * * 'currentPage'=>The page being viewed
	 * * 'totalResults'=>Total amount of results. Used in pagination
	 *
	 * @var array
	 */
	public $queries = array();
	
	/**
	 * Pointer to the current active query within the array of nested queries.
	 *
	 * @var int
	 */
	protected $queryPointer = -1;
	
	/**
	 * Parameters taken from the initialize function
	 *
	 * @var array
	 * @see \application\initializers\ContentQuery::initQuery()
	 */
	protected $params = array();
	
	/**
	 * @deprecated
	 */
	protected $lastPage;
	
	/**
	 * @deprecated
	 */
	protected $totalResults;
	
	/**
	 * @deprecated
	 */
	protected $currentPage;
	
	/**
	 * @deprecated
	 */
	protected $limit;
	
	
	/**
	 * Parses and cleans a parameters variable, either as a query string or an array
	 *
	 * @param mixed $parameters
	 * @return array Array of cleaned parameters
	 */
	protected static function parseParameters($parameters) {
		global $concerto;
		
		if(!is_array($parameters)) {
			parse_str($parameters, $parameters);
		}
		
		$clean = function($value) {
			if(strpos($value, ',') !== FALSE) {
				$value = explode(',', $value);
			}
			return $value;
		};
		
		return \application\utilities\Utility::arrayFunction($parameters, $clean);
		
		
	}
	
	/**
	 * Placeholder for the build query function in a subclass
	 *
	 * @param mixed $parameters Array or query string of query parameters
	 */
	public function buildQuery($parameters) {}
	
	/**
	 * Gets the current result in the loop as defined by the array's internal pointer
	 *
	 * @param int $queriesBack Optionally grab a result from another query in the nest
     * @return object Either \application\models\Content or \application\models\User, depending upon query
	 */
	public function getCurrentResultPointer($queriesBack = 0) {
		return current($this->queries[$this->queryPointer - $queriesBack]['results']);
		
	}
	
	/**
	 * Gets the current query result in the loop
	 *
	 * There were some issues in just using current() on the array for all calls to the current
	 * result, so we set it like this instead. We just use current() once to set it, and then access
	 * the result using this function
	 *
	 * @param int $queriesBack Optionally grab a result from another query in the nest
	 * @return object Either \application\models\Content or \application\models\User, depending upon query
	 */
	public function getCurrentResult($queriesBack = 0) {
		return $this->queries[$this->queryPointer - $queriesBack]['current'];
	}
	
	/** 
	 * Sets the current result for data access and moves the internal pointer to the next result
	 */
	public function initResult() {
		$this->queries[$this->queryPointer]['current'] = $this->getCurrentResultPointer();
		next($this->queries[$this->queryPointer]['results']);
		
	}
	
	/**
	 * Pops the query out of the nest
	 */
	public function endQuery() {
		$this->queryPointer = $this->queryPointer - 1;
		array_pop($this->queries);
	}
	
	/**
	 * Displays page links for the current query if necessary
	 */
	public function pageLinks() {
		global $concerto;
		$previous = $this->queries[$this->queryPointer]['currentPage'] - 1;
		$next = $this->queries[$this->queryPointer]['currentPage']+1;
		$last = $this->queries[$this->queryPointer]['lastPage'];
		$page = $this->queries[$this->queryPointer]['currentPage'];
		$limit = $this->queries[$this->queryPointer]['limit'];
		$total = $this->queries[$this->queryPointer]['totalResults'];

		if($total > $limit) {
			?><ul class="page-links"><?php
			
			
			if($page < 1) {
				$page = 1;
			}
			if($page > 1) : 
				setUrlQueryVar('page', $previous);
			?>
				<li><a class="next-previous" href="<?=currentUrl()?>">&larr; Prev</a></li>
			<?php endif;
			if($last < 5) {
				$max = $last;
			}
			else {
				$max = 5;
			}
			
			
			if($page < 4 && ($page < ($last - 2) || $last <= 3)) {
				for($i=1; $i<=$max; $i++) : 
					if($i == $page) { echo '<li class="current-page">'.$page.'</li>'; }
					else { 
					setUrlQueryVar('page', $i);
					?>
					<li><a class="page-number" href="<?=currentUrl()?>"><?=$i?></a></li>
				<?php } endfor;
				
			}
			elseif($last - $page > 1) { // In the middle
				$start = $page - 2;
				$end = $page + 2;
				if($start < 1) {
					$start = 1;
				}
				if($end > $last) {
					$end = $last;
				}
				?>
				<?php
				for($i=$start; $i<=$end; $i++) : 
					if($i == $page) { echo "<li class='current-page'>$page</li>"; }
					else { 
					setUrlQueryVar('page', $i);
					?>
					<li><a class="page-number" href="<?=currentUrl()?>"><?=$i?></a></li>
				<?php } endfor; ?>
				<?php
			}
			elseif($last - $page > 0) { // It's at the end
				$start = $page - 3;
				if($start < 1) {
					$start = 1;
				}
				$end = $page + 1;
				for($i=$start; $i<=$end; $i++) : 
					if($i == $page) { echo "<li class='current-page'>$page</li>"; }
					else { 
					setUrlQueryVar('page', $i);
					?>
					<li><a class="page-number" href="<?=currentUrl()?>"><?=$i?></a></li>
				<?php } endfor;					

			}
			else {
				$start = $last - 4;
				if($start < 1) {
					$start = 1;
				} 
				
				 for($i=$start; $i<=$last; $i++) : 
					if($i == $page) { echo "<li class='current-page'>$page</li>"; }
					else { 
					setUrlQueryVar('page', $i);
					?>
					<li><a class="page-number" href="<?= currentUrl()?>"><?=$i?></a></li>
				<?php } endfor;
			}
			if($page < $last) : 
				setUrlQueryVar('page', $next);
			?>
				<li><a class="next-previous" href="<?= currentUrl()?>">Next &rarr;</a></li>
			<?php endif;
			
			?></ul><?php
		
		}
	}
}

?>